import { useAppConfiguration } from "@/app/components/providers/ServerAppConfigurationProvider"; import { ErrorTag } from "@/app/components/reuseableUI/errorTag"; import ModalLayout from "@/app/components/reuseableUI/modalLayout"; import PrimaryButton from "@/app/components/reuseableUI/primaryButton"; import Toast from "@/app/components/reuseableUI/Toast"; import { SpinnerIcon } from "@/app/utils/svgs/spinnerIcon"; import { GET_PRODUCT_INQUIRY_FORM, InquiryPageData, } from "@/graphql/queries/productInquiry"; import { useRecaptcha } from "@/hooks/useRecaptcha"; import { useQuery } from "@apollo/client"; import { usePathname } from "next/navigation"; import React, { useEffect, useState } from "react"; import ReCAPTCHA from "react-google-recaptcha"; const ItemInquiryModal = ({ isModalOpen, onClose, }: { isModalOpen: boolean; onClose: () => void; }) => { const { data, loading: queryLoading, error, } = useQuery(GET_PRODUCT_INQUIRY_FORM, { variables: { first: 1 }, }); const [formData, setFormData] = useState>({}); const [fieldErrors, setFieldErrors] = useState>({}); const [showSuccessToast, setShowSuccessToast] = useState(false); const [loading, setLoading] = useState(false); const { recaptchaRef, resetRecaptcha } = useRecaptcha(); const config = useAppConfiguration(); const [recaptchaValue, setRecaptchaValue] = useState(null); const [apiError, setApiError] = useState(null); const pathname = usePathname(); const validateEmail = (email: string): boolean => { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); }; const getFieldKey = (field: string): string => { return field.toLowerCase().replace(/[^a-z0-9]/g, ""); }; const getFieldPlaceholder = (field: string): string => { const placeholders: Record = { name: "Enter Your Full Name", email: "Enter Your Email", phone: "Enter Your Phone Number", subject: "Enter Subject", message: "Type your message here...", }; const key = getFieldKey(field); return placeholders[key] || `Enter ${field}`; }; const productInquiryPageData: InquiryPageData | null = React.useMemo(() => { if (!data?.pages?.edges?.length) return null; const node = data.pages.edges[0].node; const metadata = node.metadata.reduce( (acc: Record, item: { key: string; value: string }) => { acc[item.key] = item.value; return acc; }, {} ); return { id: node.id, title: node.title, contactFormEnabled: metadata.contact_form === "true", productInquiryFormEnabled: metadata.product_inquiry_form === "true", recaptchaEnabled: metadata.reCAPTCHA === "true", fields: metadata.fields ? metadata.fields.split(",").map((f: string) => f.trim()) : [], description: metadata.description || null, emailTo: metadata.email_to || null, emailCc: metadata.email_cc || null, emailBcc: metadata.email_bcc || null, emailSubject: metadata.email_subject || null, successMessage: metadata.success_message || null, }; }, [data]); useEffect(() => { if (productInquiryPageData?.fields) { const initialFormData: Record = {}; productInquiryPageData.fields.forEach((field) => { const fieldKey = field.toLowerCase().replace(/[^a-z0-9]/g, ""); initialFormData[fieldKey] = ""; }); setFormData(initialFormData); } }, [productInquiryPageData]); const handleChange = ( e: React.ChangeEvent ) => { if (e.target.type === "number" && e.target.value.length <= 17) { setFormData({ ...formData, [e.target.name]: e.target.value, }); } else if (e.target.type !== "number") { setFormData({ ...formData, [e.target.name]: e.target.value, }); } // Clear field error when user starts typing if (fieldErrors[e.target.name]) { setFieldErrors({ ...fieldErrors, [e.target.name]: "", }); } }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setApiError(null); setShowSuccessToast(false); setFieldErrors({}); const errors: Record = {}; let hasError = false; if ( productInquiryPageData?.fields .find((f) => f.toLowerCase() === "address line 2") ?.toLowerCase() !== "address line 2" ) { // Validate all fields productInquiryPageData?.fields.forEach((field) => { const fieldKey = getFieldKey(field); const value = formData[fieldKey]; if (!value || !value.trim()) { errors[fieldKey] = `${field} is required.`; hasError = true; } else if (fieldKey === "email" && !validateEmail(value)) { errors[fieldKey] = "Please enter a valid email address."; hasError = true; } }); } // Validate reCAPTCHA if enabled if (productInquiryPageData?.recaptchaEnabled && !recaptchaValue) { errors.recaptcha = "Please complete the reCAPTCHA verification."; hasError = true; } if (hasError) { setFieldErrors(errors); return; } setLoading(true); try { // Prepare email message const emailMessage: Record = { productUrl: typeof window !== "undefined" ? window.location.href : pathname, }; productInquiryPageData?.fields.forEach((field) => { const fieldKey = getFieldKey(field); emailMessage[fieldKey] = formData[fieldKey]; }); // Prepare email recipients const recipients: string[] = []; if (productInquiryPageData?.emailTo) { recipients.push( ...productInquiryPageData.emailTo.split(",").map((e) => e.trim()) ); } const ccRecipients: string[] = []; if (productInquiryPageData?.emailCc) { ccRecipients.push( ...productInquiryPageData.emailCc.split(",").map((e) => e.trim()) ); } const bccRecipients: string[] = []; if (productInquiryPageData?.emailBcc) { bccRecipients.push( ...productInquiryPageData.emailBcc.split(",").map((e) => e.trim()) ); } const response = await fetch("/api/form-submission", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ formType: "quote", pageSlug: "product-inquiry", data: emailMessage, metadata: { to: recipients, cc: ccRecipients.length > 0 ? ccRecipients : undefined, bcc: bccRecipients.length > 0 ? bccRecipients : undefined, subject: productInquiryPageData?.emailSubject || "Quote Request", }, timestamp: new Date().toISOString(), }), }); if (!response.ok) { throw new Error("Failed to submit form"); } onClose(); // Show success toast setShowSuccessToast(true); // Reset form const resetFormData: Record = {}; productInquiryPageData?.fields.forEach((field) => { const fieldKey = getFieldKey(field); resetFormData[fieldKey] = ""; }); setFormData(resetFormData); // Reset reCAPTCHA if (productInquiryPageData?.recaptchaEnabled) { setRecaptchaValue(null); resetRecaptcha(); } // Scroll to top to see the toast window.scrollTo({ top: 0, behavior: "smooth" }); } catch (err) { console.error("Contact form submission error:", err); setApiError("Failed to send your message. Please try again later."); // Reset reCAPTCHA on error if (productInquiryPageData?.recaptchaEnabled) { setRecaptchaValue(null); resetRecaptcha(); } } finally { setLoading(false); } }; if (queryLoading) { return (
{SpinnerIcon}
); } if (error || !productInquiryPageData) { return (

Unable to load contact page. Please try again later.

); } return ( <>

{"Product Inquiry"}

{productInquiryPageData.description}

{productInquiryPageData.fields.map((field) => { const fieldKey = getFieldKey(field); const isMessageField = fieldKey === "message"; if (isMessageField) return null; return (
{fieldErrors[fieldKey] && (
{fieldErrors[fieldKey]}
)}
); })}
{productInquiryPageData.fields.some( (field) => getFieldKey(field) === "message" ) && (